#include "bios.h"
#include "dos.h"
#include "view.c"

#define UP     0x48
#define DOWN   0x50
#define RIGHT  0x4d
#define LEFT   0x4b
#define ESC    27
#define ENTER  13

#define KEY union key
union key
{
 int key;
 char ch[2];
};

#define MENU struct menu

struct menu
{
 VIEW view;
 int  xnum;
 int  ynum;
 char **items;
 int  curx;
 int  cury;
 int  itemlen;
};

void cursor(int i,int j)
{
 union REGS in;
 in.h.ah=1;
 in.h.ch=i;
 in.h.cl=j;
 int86(0x10,&in,&in);
}

void hidecursor()
{
 cursor(1,0);
 return;
}

void showcursor()
{
 cursor(6,7);
 return;
}

void Menu_init(MENU *menu,int x,int y,int xnum,int ynum,
	       char **items,int backcolor,int textcolor,int border)
{
 int len,width,height;
 int i,num=xnum*ynum;

 menu->itemlen=0;
 for(i=0;i<num;i++)
 {
  len=strlen(items[i]);
	if(menu->itemlen<len)
	   menu->itemlen=len;
 }
 menu->itemlen+=2;

 if(border==NOBORDER)
 {
  width=xnum*menu->itemlen;
  height=ynum;
 }
 else
  {
   width=xnum*menu->itemlen+2;
   height=ynum+2;
  }

 View_init(&menu->view,x,y,width,height,backcolor,textcolor,border);

 menu->xnum=xnum;
 menu->ynum=ynum;
 menu->items=items;
 menu->curx=0;
 menu->cury=0;
}

void Menu_showcuritem(MENU *menu,int anti)
{
 View_putstring(&menu->view,menu->curx*menu->itemlen+1,menu->cury,
				menu->items[menu->cury*menu->xnum+menu->curx],anti);
}

int Menu_open(MENU *menu)
{
 int i,j;
 if(menu->view.status==OPEN)
   return 1;
 if(!View_open(&menu->view))
   return 0;

 for(j=0;j<menu->ynum;j++)
   {
		for(i=0;i<menu->xnum;i++)
		  {
		   View_putstring(&menu->view,i*menu->itemlen+1,j,
						  menu->items[j*menu->xnum+i],NORMAL);
		  }
   }
 Menu_showcuritem(menu,ANTI);
 return 1;
}

void Menu_close(MENU *menu)
{
 View_close(&menu->view);
}

int Menu_drive(MENU *menu)
{
 KEY key;
 if(menu->view.status==CLOSE)
   {
	Menu_open(menu);
   }
 while(1)
   {
    key.key=bioskey(0);
	if(key.ch[0])
	 {
	  if(key.ch[0]==ESC)
	    return -1;
	  if(key.ch[0]==ENTER)
	    return menu->cury*menu->xnum+menu->curx;
	 }
	 else
	   {
	    Menu_showcuritem(menu,NORMAL);
		switch(key.ch[1])
		  {
		   case UP:
			 menu->cury=menu->cury<=0? menu->ynum-1:menu->cury-1;
			 break;
		   case DOWN:
			 menu->cury=(menu->cury>=menu->ynum-1)? 0:menu->cury+1;
			 break;
		   case LEFT:
			 menu->curx=menu->curx<=0? menu->xnum-1:menu->curx-1;
			 break;
		   case RIGHT:
			 menu->curx=(menu->curx>=menu->xnum-1)? 0:menu->curx+1;
			 break;
		  }
             Menu_showcuritem(menu,ANTI);
	 }
   }
}